home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / util / misc / ClockFreq.lha / Source / ClockFreq.mod < prev   
Encoding:
Text File  |  1996-08-17  |  6.1 KB  |  275 lines

  1. (* Module for M2Amiga (soon to by cycloned). If you want to
  2.    translate this to another HLL, then watch for the
  3.    procedure sizes, they should fit into a 256Byte
  4.    cache for best results *)
  5.  
  6.  
  7.  
  8. MODULE ClockFreq;
  9.  
  10.  
  11. IMPORT ED: ExecD;
  12. IMPORT EL: ExecL;
  13. IMPORT DL: DosL;
  14. FROM Hardware IMPORT ciaa, ciab;
  15.  
  16. IMPORT R;
  17. IMPORT CO: Conversions;
  18. IMPORT LRC: LongRealConversions;
  19.  
  20. FROM CiaTimer IMPORT CiaStartTimer, CiaStopTimer, CiaGetDiff;
  21.  
  22. FROM SYSTEM IMPORT CAST, ADDRESS, ADR, ASSEMBLE, BITSET;
  23.  
  24.  
  25.  
  26. CONST
  27.    Version= "$VER: ClockFreq 1.0 (16.08.1996)";
  28.  
  29. VAR
  30.    OuterLoopVal, InnerLoopVal: INTEGER;  (* Times to run through the NOP-Loop *)
  31.    ClocksPerNOP: LONGINT;   (* How many clocks does a NOP use on a specific CPU *)
  32.  
  33.  
  34.  
  35. (* Some custom IO *)
  36. (*$CopyDyn:= FALSE *)
  37. PROCEDURE W(S: ARRAY OF CHAR);
  38. VAR
  39.    Bool{R.D7}: BOOLEAN;
  40. BEGIN
  41.    Bool:= DL.PutStr(ADR(S));
  42. END W;
  43.  
  44. PROCEDURE WI(LI, W: LONGINT);
  45. VAR
  46.    Bool{R.D7}, err: BOOLEAN;
  47.    S: ARRAY [0..15] OF CHAR;
  48. BEGIN
  49.    CO.ValToStr(LI, FALSE, S, 10, W, " ", err);
  50.    Bool:= DL.PutStr(ADR(S));
  51. END WI;
  52.  
  53. PROCEDURE WR(LR: LONGREAL; M, N: LONGINT);
  54. VAR
  55.    Bool{R.D7}, err: BOOLEAN;
  56.    S: ARRAY [0..15] OF CHAR;
  57. BEGIN
  58.    LRC.RealToStr(LR, S, M, N , FALSE, err);
  59.    Bool:= DL.PutStr(ADR(S));
  60. END WR;
  61.  
  62.  
  63.  
  64.  
  65. (* Measure frequency by doing nothing ...
  66.    A NOP is perfect for measuring MHz, because it synchronises the
  67.    cpu-pipelines and it is therefore easy to say how much clocks
  68.    are needed for one NOP. The influence of the loops (DBF) is
  69.    compensated in a second measuring. *)
  70.  
  71. CONST
  72.    NumNOPs= 40;
  73.  
  74. (*$EntryExitCode:= FALSE *)
  75. PROCEDURE NOPLoop(InnerLoop{R.D5}, OuterLoop{R.D6}: INTEGER);
  76. BEGIN
  77.    ASSEMBLE(
  78.        OLoop:
  79.           MOVE.W D5, D0
  80.        Loop:
  81.           NOP  (*Inst 1*)
  82.           NOP
  83.           NOP
  84.           NOP
  85.           NOP
  86.           NOP
  87.           NOP
  88.           NOP
  89.           NOP
  90.           NOP
  91.           NOP
  92.           NOP
  93.           NOP
  94.           NOP
  95.           NOP
  96.           NOP
  97.           NOP
  98.           NOP
  99.           NOP
  100.           NOP
  101.           NOP  (*Inst 21*)
  102.           NOP
  103.           NOP
  104.           NOP
  105.           NOP
  106.           NOP
  107.           NOP
  108.           NOP
  109.           NOP
  110.           NOP
  111.           NOP
  112.           NOP
  113.           NOP
  114.           NOP
  115.           NOP
  116.           NOP
  117.           NOP
  118.           NOP
  119.           NOP
  120.           NOP
  121.           NOP  (* 41, these 6 are for overhead measuring *)
  122.           NOP
  123.           NOP
  124.           NOP
  125.           NOP
  126.           NOP
  127.           DBF D0, Loop
  128.           DBF D6, OLoop
  129.           RTS
  130.           END);
  131. END NOPLoop;
  132.  
  133.  
  134. (*$EntryExitCode:= FALSE *)
  135. PROCEDURE Overhead(InnerLoop{R.D5}, OuterLoop{R.D6}: INTEGER);
  136. BEGIN
  137.    ASSEMBLE(
  138.        OLoop:
  139.           MOVE.W D5, D0
  140.        Loop:
  141.           NOP  (* 41, these 6 are for overhead measuring *)
  142.           NOP
  143.           NOP
  144.           NOP
  145.           NOP
  146.           NOP
  147.           DBF D0, Loop
  148.           DBF D6, OLoop
  149.           RTS
  150.           END);
  151. END Overhead;
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158. PROCEDURE SlowCalc;
  159. VAR
  160.    Ticks: LONGINT;   (* Ticks per second *)
  161.    Used: LONGINT;    (* used ticks *)
  162.    HelpR: LONGREAL;
  163.  
  164. BEGIN
  165.    Ticks:= EL.execBase^.eClockFrequency;
  166.  
  167.    (* Interrupts must be diabled to measure frequency as good as possible.
  168.       This forbids using ReadEClock, and forbids to combine two
  169.       cia-timers to one (???). So the maximum tick-time is 2^16. *)
  170.    EL.Disable;
  171.  
  172.    (* Approx. time for 1 loop, to see how many loops fit in 2^16-1 ticks *)
  173.    CiaStartTimer;
  174.    NOPLoop(InnerLoopVal, 0);
  175.    CiaStopTimer;
  176.    Used:= CiaGetDiff();
  177.  
  178.    IF Used > 0 THEN
  179.       OuterLoopVal:= (65535 DIV Used) ;
  180.  
  181.       (* REPEAT for handling unexpected circumstances... *)
  182.       REPEAT
  183.          DEC(OuterLoopVal);
  184.  
  185.          NOPLoop(InnerLoopVal, 0);  (* Preload Cache \                           *)
  186.          CiaStartTimer;             (*                - should fit in 256B-cache *)
  187.          CiaStopTimer;
  188.          CiaStartTimer;
  189.          NOPLoop(InnerLoopVal, OuterLoopVal);    (*  /                           *)
  190.          CiaStopTimer;
  191.          Used:= CiaGetDiff();
  192.       UNTIL (Used > 0) OR (OuterLoopVal < 0);  (* Used = 0 if ticks >=2^16 *)
  193.  
  194.       IF OuterLoopVal >= 0 THEN
  195.          (* Overhead timing *)
  196.          Overhead(InnerLoopVal, 0);  (* Preload Cache *)
  197.          CiaStartTimer;
  198.          CiaStopTimer;
  199.          CiaStartTimer;
  200.          Overhead(InnerLoopVal, OuterLoopVal);
  201.          CiaStopTimer;
  202.  
  203.          EL.Enable;
  204.  
  205.          DEC(Used, CiaGetDiff());
  206.  
  207.          HelpR:= LONGREAL((InnerLoopVal+1)*ClocksPerNOP*(OuterLoopVal+1));   (* DBF needs +1 *)
  208.          HelpR:= HelpR / (LONGREAL(Used) / LONGREAL(Ticks));
  209.  
  210.          (* Print results. "/ 25000", because result should be in Mhz and not Hz and
  211.             because 40 NOPs used and not one *)
  212.          W("CPU:         "); WR(HelpR / 25000., 10, 5); W(" MHz\n");
  213.          W("Ticks:  "); WI(Used, 10); W("\n");
  214.          W("Ticks/s:"); WI(Ticks, 10); W("\n");
  215.          (* W("Loops:  "); WI(OuterLoopVal, 10); W("\n"); *)
  216.       END;
  217.    ELSE
  218.       EL.Enable;
  219.       W("Measurement impossible. Enable cache or install fastram ...");
  220.    END;
  221. END SlowCalc;
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231. VAR
  232.    Bool, CacheChk: BOOLEAN;
  233. BEGIN
  234.    (* Show BOLD version to user *)
  235.    W("\e[1m");   Bool:= DL.PutStr(ADR(Version)+6);   W("\e[0m\n");
  236.  
  237.  
  238.    (* Adapt to CPU *)
  239.    CacheChk:= TRUE;
  240.    IF ED.af7 IN EL.execBase^.attnFlags THEN   (* supported by all 060-boards??? *)
  241.       W("060 mode\n");
  242.       InnerLoopVal:= 99;
  243.       ClocksPerNOP:= 9;
  244.    ELSIF ED.m68040 IN EL.execBase^.attnFlags THEN
  245.       W("040 mode\n");
  246.       InnerLoopVal:= 99;
  247.       ClocksPerNOP:= 8;
  248.    ELSIF ED.m68020 IN EL.execBase^.attnFlags THEN
  249.       W("020|030 mode\n");
  250.       InnerLoopVal:= 199;
  251.       ClocksPerNOP:= 2;
  252.    ELSE
  253.       W("000|010 mode\n");
  254.       InnerLoopVal:= 69;
  255.       ClocksPerNOP:= 4;
  256.       CacheChk:= FALSE;
  257.    END;
  258.  
  259.    (* Test for optimal conditions *)
  260.    IF CacheChk THEN   (* verify that cache is turned on *)
  261.       IF ~(ED.enableI IN EL.CacheControl(ED.CacheFlagSet{}, ED.CacheFlagSet{})) THEN
  262.          W("\e[3mInstructionCache not enabled, result will be inexact ...\e[0m\n");
  263.       END;
  264.    ELSE   (* check that code is in "fast" on 68000/010 *)
  265.       IF ~(ED.fast IN EL.TypeOfMem(ADR(NOPLoop))) THEN
  266.          W("\e[3mProgram is not in fast ram, result will be inexact ...\e[0m\n");
  267.       END;
  268.    END;
  269.  
  270.    DL.Delay(5);   (* SystemCalmDown *)
  271.  
  272.    SlowCalc;
  273.  
  274. END ClockFreq.
  275.